package com.lx.preferred.mall.authcenter.config;

import com.lx.preferred.mall.authcenter.enhancer.PreferredMallTokenEnhancer;
import com.lx.preferred.mall.authcenter.service.PreferredUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author lX
 * @version JDK 8
 * @className PreferredMallAuthorizationServerConfig (此处以class为例)
 * @date 2024/12/3
 * @description 优选商城认证服务器配置
 */

@Configuration
@EnableAuthorizationServer //开启授权服务
public class PreferredMallAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
  @Resource
  private DataSource dataSource;

  @Resource
  private PreferredUserDetailService userDetailService;



  @Resource
  private AuthenticationManager authenticationManagerBean;

  @Qualifier("jwtTokenStore")
  @Resource
  private  TokenStore tokenStore;

  @Autowired
  private JwtAccessTokenConverter jwtAccessTokenConverter;

  @Autowired
  private PreferredMallTokenEnhancer tokenEnhancer;

  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
    List<TokenEnhancer> delegates = new ArrayList<>();
    delegates.add(tokenEnhancer);
    delegates.add(jwtAccessTokenConverter);
    enhancerChain.setTokenEnhancers(delegates);


    endpoints.authenticationManager(authenticationManagerBean)//密码模式需要注入该Bean
      .tokenStore(tokenStore)
      .accessTokenConverter(jwtAccessTokenConverter)
      .tokenEnhancer(enhancerChain)
      .reuseRefreshTokens(false)
      .userDetailsService(userDetailService)
      .allowedTokenEndpointRequestMethods(HttpMethod.GET,HttpMethod.POST);
  }

  @Override
  public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
      security.checkTokenAccess("isAuthenticated()")//调用checkToken是否需要携带clientId和Secret
        .tokenKeyAccess("isAuthenticated()")//获取tokenKey是否需要携带clientId和Secret
        .allowFormAuthenticationForClients();
  }

  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.withClientDetails(clientDetails());//客户端配置
  }

  @Bean
  public ClientDetailsService clientDetails(){
    return new JdbcClientDetailsService(dataSource);//从数据库查询客户端信息
  }
}
